/*
 * Sylvain BERTRAND <digital.ragnarok@gmail.com>
 * code protected by GNU GPL v3
 */
#include <X11/Xlib.h>
#include <glib.h>
#include <libxml/xinclude.h>
#include "../../toolkit/keyboard.h"
#include "../../toolkit/xml.h"
#include "../misc.h"
#include "../geom.h"
#include "../frame.h"
#include "../actions.h"
#include "../window.h"
#include "../stacking.h"
#include "../client.h"
enum max_direction { BOTH = 0, HORZ = 1, VERT = 2 };
struct options {
	enum max_direction dir;
};

static gpointer setup_func(xmlNodePtr node)
{
	xmlNodePtr n;
	struct options *o;
	o = g_slice_new0(struct options);
	o->dir = BOTH;
	if((n = t_xml_find_node(node, "direction"))) {
		gchar *s = t_xml_node_string(n);
		if(!g_ascii_strcasecmp(s, "vertical") || !g_ascii_strcasecmp(s, "vert"))
			o->dir = VERT;
		else if(!g_ascii_strcasecmp(s, "horizontal") || !g_ascii_strcasecmp(s, "horz"))
			o->dir = HORZ;
		g_free(s);
	}
	return o;
}

static void free_func(gpointer o)
{
	g_slice_free(struct options, o);
}

static gboolean run_func_on(struct wm_actions_data *data, gpointer options)
{
	struct options *o = options;
	if(data->client) {
		actions_client_move(data, TRUE);
		client_maximize(data->client, TRUE, o->dir);
		actions_client_move(data, FALSE);
	}
	return FALSE;
}

static gboolean run_func_off(struct wm_actions_data *data, gpointer options)
{
	struct options *o = options;
	if(data->client) {
		actions_client_move(data, TRUE);
		client_maximize(data->client, FALSE, o->dir);
		actions_client_move(data, FALSE);
	}
	return FALSE;
}

static gboolean run_func_toggle(struct wm_actions_data *data, gpointer options)
{
	struct options *o = options;
	if(data->client) {
		gboolean toggle;
		actions_client_move(data, TRUE);
		toggle = ((o->dir == HORZ && !data->client->max_horz) || (o->dir == VERT && !data->client->max_vert) || (o->dir == BOTH
				&& !(data->client->max_horz && data->client->max_vert)));
		client_maximize(data->client, toggle, o->dir);
		actions_client_move(data, FALSE);
	}
	return FALSE;
}

static gpointer setup_both_func(xmlNodePtr node)
{
	struct options *o = g_slice_new0(struct options);
	(void)node;
	o->dir = BOTH;
	return o;
}

static gpointer setup_horz_func(xmlNodePtr node)
{
	struct options *o = g_slice_new0(struct options);
	(void)node;
	o->dir = HORZ;
	return o;
}

static gpointer setup_vert_func(xmlNodePtr node)
{
	struct options *o = g_slice_new0(struct options);
	(void)node;
	o->dir = VERT;
	return o;
}

void action_maximize_startup(void)
{
	actions_register("Maximize", setup_func, free_func, run_func_on);
	actions_register("Unmaximize", setup_func, free_func, run_func_off);
	actions_register("ToggleMaximize", setup_func, free_func, run_func_toggle);
	actions_register("MaximizeFull", setup_both_func, free_func, run_func_on);
	actions_register("UnmaximizeFull", setup_both_func, free_func, run_func_off);
	actions_register("ToggleMaximizeFull", setup_both_func, free_func, run_func_toggle);
	actions_register("MaximizeHorz", setup_horz_func, free_func, run_func_on);
	actions_register("UnmaximizeHorz", setup_horz_func, free_func, run_func_off);
	actions_register("ToggleMaximizeHorz", setup_horz_func, free_func, run_func_toggle);
	actions_register("MaximizeVert", setup_vert_func, free_func, run_func_on);
	actions_register("UnmaximizeVert", setup_vert_func, free_func, run_func_off);
	actions_register("ToggleMaximizeVert", setup_vert_func, free_func, run_func_toggle);
}
